﻿//
// SymbolTable.cs
//

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ASTClass;

namespace Taste
{

    public class Var
    {
        public AST variable;
        public AST proc;
        public int index;

        public Var(AST variable)
        {
            this.variable = variable;
        }
    }

    class Scope
    {
        public List<Var> vars = new List<Var>();
        public Scope parent;
        public String proc = "";
    }

    public class SymbolTable
    {
        Scope globalScope = new Scope();
        Scope currentScope;
        int localIndex = 0;
        int globalIndex = 0;

        public SymbolTable()
        {
            currentScope = globalScope;
        }

        public void OpenScope(String proc)
        {
            Scope newScope = new Scope();
            newScope.proc = proc;
            newScope.parent = currentScope;
            currentScope = newScope;
        }

        public void CloseScope()
        {
            currentScope = currentScope.parent;
        }

        public Var findLocalVar(String varname)
        {
            Scope curs = currentScope;
            while (curs.parent != null)
            {
                foreach (Var l in curs.vars)
                {
                    IdentAST cur = l.variable as IdentAST;
                    if (varname == cur.Value)
                    {
                        return l;
                    }
                }
                curs = curs.parent;
            }
            return null;
        }

        public Var findGlobalVar(String varname)
        {
            foreach (Var g in globalScope.vars)
            {
                IdentAST cur = g.variable as IdentAST;
                if (varname == cur.Value)
                {
                    return g;
                }
            }
            return null;
        }

        public void insertLocalVar(Var var)
        {
            var.index = localIndex++;
            currentScope.vars.Add(var);
        }

        public void insertGlobalVar(Var var)
        {
            var.index = globalIndex++;
            globalScope.vars.Add(var);
        }

        public int numLocals(String procname)
        {
            return currentScope.vars.Count;
        }
    }
}
